package center.leon.zoomanualsentinel.runner;

import center.leon.zoocommon.holder.DynamicValueHolder;
import com.alibaba.csp.sentinel.Entry;
import com.alibaba.csp.sentinel.SphU;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.RuleConstant;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRule;
import com.alibaba.csp.sentinel.slots.block.flow.FlowRuleManager;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

/**
 * @author : Leon on XXM Mac
 * @since : create in 2024/8/19 17:05
 */
@Slf4j
@Component
public class MonkeyRunner implements ApplicationRunner {

    @Resource
    private ApplicationContext applicationContext;

    @Override
    public void run(ApplicationArguments args) throws Exception {
        DynamicValueHolder holder = applicationContext.getBean(DynamicValueHolder.class);
        this.initFlowRules();
        for(;;){
            Entry entry = null;
            try{
                entry = SphU.entry("HelloWorld");
                // your biz - start
                log.info("Hello World");
                TimeUnit.MILLISECONDS.sleep(40);
                if(Objects.equals(holder.getABreak(), true)){
                    log.info("Break!");
                    return;
                }
                // your biz - finish
            }catch (BlockException e){
                // flow control - start
                log.info("Blocked!");
                // flow control - finish
            }finally {
                if(Objects.nonNull(entry)){
                    entry.exit();
                }
            }
        }
    }

    private void initFlowRules() {
        List<FlowRule> rules = Lists.newArrayList();
        FlowRule rule = new FlowRule();
        rule.setResource("HelloWorld");
        rule.setGrade(RuleConstant.FLOW_GRADE_QPS);
        // Set limit QPS to 20.
        rule.setCount(20);
        rules.add(rule);
        FlowRuleManager.loadRules(rules);
    }
}
